#include "Queue.h"

void QueueInit(Queue* q) {
	assert(q);
	q->_front = q->_rear = NULL;
}

Queue* QueueCreate() {
	Queue* newqueue = (Queue*)malloc(sizeof(Queue));
	if (newqueue == NULL) {
		perror("malloc fail");
		exit(1);
	}
	return newqueue;
}

void QueueDestroy(Queue* q) {
	assert(q);
	QNode* tmp = q->_front;
	QNode* del = tmp;
	while (tmp) {
		del = tmp;
		tmp = tmp->_next;
		free(del);
	}
	del = NULL;
	q->_front = q->_rear = NULL;
	free(q);
}

void QueuePush(Queue* q, const QDataType data) {
	assert(q);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (!newnode) {
		perror("malloc fail!");
		exit(1);
	}
	newnode->val = data;
	newnode->_next = NULL;
	if (!q->_rear) {
		q->_front = q->_rear = newnode;
	}
	else {
		q->_rear->_next = newnode;
		q->_rear = q->_rear->_next;
		q->_rear->_next = NULL;
	}
}

void QueuePop(Queue* q) {
	assert(q);
	if (!q->_front) {
		return;
	}
	else if (q->_front == q->_rear) {
		free(q->_front);
		q->_front = q->_rear = NULL;
	}
	else {
		QNode* del = q->_front;
		q->_front = q->_front->_next;
		free(del);
		del = NULL;
	}
}

QDataType QueueFront(Queue* q) {
	assert(q);
	if (!q->_front) {
		printf("Queue is NULL\n");
		return -1;
	}
	return q->_front->val;
}

QDataType QueueBack(Queue* q) {
	assert(q);
	if (!q->_rear) {
		printf("Queue is NULL\n");
		return -1;
	}
	return q->_rear->val;
}

int QueueSize(Queue* q) {
	assert(q);
	int num = 0;
	QNode* tmp = q->_front;
	while (tmp) {
		tmp = tmp->_next;
		num++;
	}
	return num;
}

int QueueEmpty(Queue* q) {
	assert(q);
	if (q->_rear) {
		return 1;
	}
	else {
		return 0;
	}
}